#include "exam.h"
#include "gtest/gtest.h"
#include <iostream>

// setuptestcase fixture
// setup everycase
extern "C" {
extern void RunFsmForTest();
}
class ExamCLangTest : public ::testing::Test {
  protected:
    virtual void SetUp() { std::cout << "setup executor" << std::endl; }
    virtual void TearDown() { std::cout << "teardown executor" << std::endl; }
    static void  SetUpTestCase() { std::cout << "setup by case" << std::endl; }
    static void  TearDownTestCase()
    {
        std::cout << "teardown by case" << std::endl;
    }
};

TEST_F(ExamCLangTest, problem_test_str_len)
{
    char  str[]     = "\\0";
    char *pcColor   = "blue1";
    char  acColor[] = "blue1";
    ASSERT_EQ(3, sizeof(str));
    ASSERT_EQ(8, sizeof(pcColor));
    ASSERT_EQ(6, sizeof(acColor));
    ASSERT_EQ(0, '\0');
}

TEST_F(ExamCLangTest, problem_test_struct)
{
    typedef struct tagABC {
        unsigned char ucpar1 : 2;
        unsigned char ucpar2 : 1;
        unsigned char ucpar3 : 7;
        unsigned char ucpar4 : 6;
        unsigned char ucpar5 : 4;
        unsigned char ucpar6 : 4;
        unsigned char ucpar7;
        unsigned char ucpar8;
    } ABC;
    ASSERT_EQ(6, sizeof(ABC));
}

typedef struct _examTblSt {
    int dividend, divisor;
    int expect; // quotient
    // void *handleFunc;
} ExamTblSt;

typedef int (*funcType)(int, int);
void ExamTest_TblTest(ExamTblSt *st, funcType handle)
{
    // funcType handle = (funcType)(st->handleFunc);
    funcType f = (funcType)handle;
    ASSERT_EQ(st->expect, f(st->dividend, st->divisor));
}

TEST_F(ExamCLangTest, main_xxsfd)
{
    int c = Exam_add(1, 3);
    ASSERT_EQ(c, 4);

    ExamTblSt g_examTblSt[] = {
        {-3, -1, 3},
        // {3, 1, 3},
        {-4, -1, 4},
    };
    int i;
    for (i = 0; i < sizeof(g_examTblSt) / sizeof(ExamTblSt); i++) {
        ExamTest_TblTest(g_examTblSt + i, Exam_div);
    }
}

// TEST_P()
TEST_F(ExamCLangTest, main_fsm) { RunFsmForTest(); }